#include "coopsched.h"
#include "cooptask.h"
#include <iostream>

enum ModeID {
	MODE_SETUP,
	MODE_MANUAL,
	MODE_AUTO
};

typedef cnc::base::CooperativeScheduler<ModeID, cnc::base::CooperativeTask> CoopScheduler;

class CooperativeMode : public cnc::base::CooperativeTask
{
protected:
	CoopScheduler *scheduler_;
	int menu()
	{
		int option;

		std::cout << "\t1. Modo de configuración" << std::endl;
		std::cout << "\t2. Modo manual" << std::endl;
		std::cout << "\t3. Modo automático" << std::endl;
		std::cout << "\t4. Salir" << std::endl;
		std::cin >> option;
		return option;
	}
public:
	CooperativeMode(CoopScheduler *scheduler) : scheduler_(scheduler) {}
	virtual void start() = 0;
	virtual bool execute() = 0;
	virtual void stop() = 0;
};

class SetupMode : public CooperativeMode
{
public:
	SetupMode(CoopScheduler *scheduler) : CooperativeMode(scheduler) {}
	virtual void start()
	{
		std::cout << "Iniciar modo de configuración." << std::endl;
	}
	virtual bool execute()
	{
		std::cout << "Modo de configuración" << std::endl;
		std::cout << "---------------------" << std::endl;
		switch (menu()) {
		case 1:
			return true;
		case 2:
			scheduler_->selectMode(MODE_MANUAL);
			return false;
		case 3:
			scheduler_->selectMode(MODE_AUTO);
			return false;
		case 4:
			return false;
		}
	}
	virtual void stop()
	{
		std::cout << "Detener modo de configuración." << std::endl;
	}
};

class ManualMode : public CooperativeMode
{
public:
	ManualMode(CoopScheduler *scheduler) : CooperativeMode(scheduler) {}
	virtual void start()
	{
		std::cout << "Iniciar modo manual." << std::endl;
	}
	virtual bool execute()
	{
		std::cout << "Modo manual" << std::endl;
		std::cout << "-----------" << std::endl;
		switch (menu()) {
		case 1:
			scheduler_->selectMode(MODE_SETUP);
			return false;
		case 2:
			return true;
		case 3:
			scheduler_->selectMode(MODE_AUTO);
			return false;
		case 4:
			return false;
		}
	}
	virtual void stop()
	{
		std::cout << "Detener modo manual." << std::endl;
	}
};

class AutoMode : public CooperativeMode
{
public:
	AutoMode(CoopScheduler *scheduler) : CooperativeMode(scheduler) {}
	virtual void start()
	{
		std::cout << "Iniciar modo automático." << std::endl;
	}
	virtual bool execute()
	{
		std::cout << "Modo automático" << std::endl;
		std::cout << "---------------" << std::endl;
		switch (menu()) {
		case 1:
			scheduler_->selectMode(MODE_SETUP);
			return false;
		case 2:
			scheduler_->selectMode(MODE_MANUAL);
			return false;
		case 3:
			return true;
		case 4:
			return false;
		}
	}
	virtual void stop()
	{
		std::cout << "Detener modo automático." << std::endl;
	}
};

class BackgroundTask : public cnc::base::CooperativeTask
{
public:
	virtual void start()
	{
		std::cout << "Iniciar tarea de segundo plano." << std::endl;
	}
	virtual bool execute()
	{
		std::cout << "Ejecutar tarea de segundo plano." << std::endl;
	}
	virtual void stop()
	{
		std::cout << "Detener tarea de segundo plano." << std::endl;
	}
};

int main()
{
	CoopScheduler scheduler;
	SetupMode setupMode(&scheduler);
	ManualMode manualMode(&scheduler);
	AutoMode autoMode(&scheduler);
	BackgroundTask bgTask;
	scheduler.addTask(&bgTask);
	scheduler.addMode(MODE_SETUP, &setupMode);
	scheduler.addMode(MODE_MANUAL, &manualMode);
	scheduler.addMode(MODE_AUTO, &autoMode);
	scheduler.start();
	scheduler.selectMode(MODE_SETUP);
	scheduler.execute();
	scheduler.stop();
	return 0;
}

